package GeneticAlgorithm;

import Individual.*;
import Loader.*;
import Settings.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;

public class Research {

    private Individual[] individuals;
    private int generation;
    private BufferedData bufferedData;
    private FitnessFunctions fitnessFunctions;
    private StatisticFunctions statisticFunctions;

    public int howMany;
    public float step;
    public float initialValue;

    public Research() {

        Loader loader = new Loader();
        bufferedData = loader.load(Settings.FILE);
        individuals = new Individual[Settings.POPULATION];
        fitnessFunctions = new FitnessFunctions(bufferedData);
        statisticFunctions = new StatisticFunctions( individuals,
                                                     fitnessFunctions,
                                                     bufferedData
                                                   );

    }

    public Research(float initialValue, float step, int howMany) {

        Loader loader = new Loader();
        bufferedData = loader.load(Settings.FILE);
        individuals = new Individual[Settings.POPULATION];
        fitnessFunctions = new FitnessFunctions(bufferedData);
        statisticFunctions = new StatisticFunctions( individuals,
                                                     fitnessFunctions,
                                                     bufferedData
                                                   );

        this.howMany = howMany;
        this.step = step;
        this.initialValue = initialValue;

    }

    public void researchPm() {

        if(bufferedData.data == null) {
            System.out.println("Brak danych!");
            return;
        }

        Settings.PROPABILITY_CROSSOVER = 0.0f;
        Settings.EXTERNAL_REPRODUCTION = false;

        float[] pmSet = new float[howMany]; //1000
        pmSet[0] = initialValue;//0.1f
        float grad = step;//0.1f / pmSet.length;
        for(int i = 1; i < pmSet.length; ++i)
            pmSet[i] = pmSet[i-1] + grad;

        int tabLength = Settings.SHUFFLE_PER_ITERATION * Settings.REPEAT_GENERATION_PER_ITERATION;

        float[] accuracy = new float[ tabLength ];
        PairIndividualFitness[] bestIndividuals = new PairIndividualFitness[ tabLength ];
        float[] acc_avg_temp = new float[tabLength];

        try {
            for(int ff = 0; ff < 3; ++ff) {
                Settings.FITNESS_FUNCTION_TYPE = ff;

                //-------------file out----------------
                String file = ff+"_acc_pm_"+initialValue+"_"+step+"_"+howMany;
                File f = new File(file+".txt");
                BufferedWriter out = new BufferedWriter(new FileWriter(f));
                out.write("# badanie accuracy od pm dla: 200 generation, 100 population, replication non external, precision 8 bits, crossvalidation 5x10, set IRIS ");
                out.newLine();
                out.write("# fitnes fun:"+(ff==0?"euclides":"dbi")+", pc=0, clusters=6");
                out.newLine();
                out.write("#Started computing: "+(new Date()));
                out.newLine();
                out.close();
                //-------------end file out----------------

                for(int j = 0; j < pmSet.length; ++j) {
                    Settings.PROPABILITY_MUTATION = pmSet[j];

                        //genetic algorithm
                        int shuffleIteration = 0;
                        int repeatGeneration = 0;
                        int iterationCounter = 0;

                        for(int i = 0; i < tabLength; ++i) {
                            accuracy[i] = 0;
                            bestIndividuals[i] = null;
                        }


                        while(shuffleIteration < Settings.SHUFFLE_PER_ITERATION) {

                            bufferedData.shuffleData(Settings.NUMBER_OF_REPEAT_SHUFFLE_DATA);
                            repeatGeneration = 0;
                            while(repeatGeneration < Settings.REPEAT_GENERATION_PER_ITERATION) {

                                Initialization.initialization(individuals, bufferedData);
                                generation = 0;
                                while(generation < Settings.GENERATION) {

                                    ReproductionFunctions.reproduction( fitnessFunctions,
                                                                        individuals,
                                                                        bufferedData
                                                                      );

                                    CrossoverFunctions.crossover( individuals );

                                    MutationFunctions.mutation( individuals );

                                    generation++;
                                }

                                PairIndividualFitness bestInd = statisticFunctions.getBestIndividual();
                                accuracy[iterationCounter] = statisticFunctions.getAverageAccuracy(true, bestInd.individual);
                                bestIndividuals[iterationCounter] = bestInd;


                                iterationCounter++;
                                repeatGeneration++;
                            }
                            shuffleIteration++;
                        }

                        //find best, avg and worst individual with bestIndividuals table
                        float acc_best_l = 0.0f;
                        float acc_best_t = 0.0f;
                        float acc_avg_l = 0.0f;
                        float acc_avg_t = 0.0f;
                        float acc_worst_l = Float.MAX_VALUE;
                        float acc_worst_t = Float.MAX_VALUE;
                        

                        for(int i = 0; i < tabLength; ++i) {
                            acc_avg_temp[i] = accuracy[i];
                            //System.out.println(acc_avg_temp[i]);
                        }
                        Arrays.sort(acc_avg_temp);
                        acc_avg_l = acc_avg_temp[(tabLength+1)/2];
                        for(int i = 0; i < tabLength; ++i)
                            if(accuracy[i] == acc_avg_l) {
                                acc_avg_t = statisticFunctions.getAverageAccuracy(false, bestIndividuals[i].individual);
                                break;
                            }
                        int acc_best_pos=0;
                        int acc_worst_pos=0;
                        for(int i = 0; i < tabLength; ++i) {
                            if(acc_best_l < accuracy[i]) {
                                acc_best_l = accuracy[i];
                                acc_best_pos = i;
                            }
                            if(acc_worst_l > accuracy[i]) {
                                acc_worst_l = accuracy[i];
                                acc_worst_pos = i;
                            }
                        }
                        acc_best_t = statisticFunctions.getAverageAccuracy(false, bestIndividuals[acc_best_pos].individual);
                        acc_worst_t = statisticFunctions.getAverageAccuracy(false, bestIndividuals[acc_worst_pos].individual);

                        String recordPlot = String.format(Locale.ENGLISH,"%.4f %.4f %.4f %.4f %.4f %.4f %.4f", pmSet[j],
                                                                                                               acc_best_l,
                                                                                                               acc_best_t,
                                                                                                               acc_avg_l,
                                                                                                               acc_avg_t,
                                                                                                               acc_worst_l,
                                                                                                               acc_worst_t);
                        out = new BufferedWriter(new FileWriter(f, true));
                        out.write(recordPlot);
                        out.newLine();
//                        out.write("# ");
//                        for(int c = 0; c < Settings.CHROMOSOME_NUMBER_OF_CLUSTERS; ++c) {
//                            for(int fe = 0; fe < Settings.CHROMOSOME_NUMBER_OF_FEATURES; ++fe)
//                                out.write(bestIndividuals[acc_best_pos].individual.chromosomeVal.get(c).get(fe)+" ");
//                            out.write("| ");
//                        }
//                        out.newLine();
                        out.close();
                        //statisticFunctions.paintRecordsAndCentres(bestIndividuals[acc_best_pos].individual, "researchIndividualChanges_ff_"+ff+"_pm_"+pmSet[j]+"param_"+initialValue+"_"+step+"_"+howMany);
                }


                //-------------file out----------------
                out = new BufferedWriter(new FileWriter(f, true));
                out.newLine();
                out.write("#Finished computing: "+(new Date()));
                out.newLine();
                out.close();
                //-------------end file out----------------
                
            }
        } catch(Exception e) {
            System.out.println("Blad zapisu wynikow:\n"+e);
        }
    }

    public void researchGeneration() {

        if(bufferedData.data == null) {
            System.out.println("Brak danych!");
            return;
        }

        Settings.PROPABILITY_CROSSOVER = 0.0f;
        Settings.PROPABILITY_MUTATION = 0.3f;
        Settings.EXTERNAL_REPRODUCTION = false;

        int[] generatrionTab = new int[howMany]; //1000
        generatrionTab[0] = (int)initialValue;//0.1f
        float grad = step;//0.1f / pmSet.length;
        for(int i = 1; i < generatrionTab.length; ++i)
            generatrionTab[i] = (int) (generatrionTab[i - 1] + grad);

        int tabLength = Settings.SHUFFLE_PER_ITERATION * Settings.REPEAT_GENERATION_PER_ITERATION;

        float[][] accuracy = new float[ tabLength ][];
        PairIndividualFitness[] bestIndividuals = new PairIndividualFitness[ tabLength ];
        float[] acc_avg_temp = new float[tabLength];

        try {
            for(int ff = 0; ff < 3; ++ff) {
                Settings.FITNESS_FUNCTION_TYPE = ff;

                //-------------file out----------------
                String file = ff+"_acc_generation_"+initialValue+"_"+step+"_"+howMany;
                File f = new File(file+".txt");
                BufferedWriter out = new BufferedWriter(new FileWriter(f));
                out.write("# badanie accuracy od generatrion dla: 50 population, replication non external, precision 8 bits, crossvalidation 5x10, set IRIS ");
                out.newLine();
                out.write("# fitnes fun:"+(ff==0?"euclides":"dbi")+", pc=0, pm=0.016 clusters=6");
                out.newLine();
                out.write("#Started computing: "+(new Date()));
                out.newLine();

                out.close();
                //-------------end file out----------------

                for(int j = 0; j < generatrionTab.length; ++j) {
                    Settings.GENERATION = generatrionTab[j];

                        //genetic algorithm
                        int shuffleIteration = 0;
                        int repeatGeneration = 0;
                        int iterationCounter = 0;

                        for(int i = 0; i < tabLength; ++i) {
                            accuracy[i] = new float[] {0, 0};
                            bestIndividuals[i] = null;
                        }


                        while(shuffleIteration < Settings.SHUFFLE_PER_ITERATION) {

                            bufferedData.shuffleData(Settings.NUMBER_OF_REPEAT_SHUFFLE_DATA);
                            repeatGeneration = 0;
                            while(repeatGeneration < Settings.REPEAT_GENERATION_PER_ITERATION) {

                                Initialization.initialization(individuals, bufferedData);
                                generation = 0;
                                while(generation < Settings.GENERATION) {

                                    ReproductionFunctions.reproduction( fitnessFunctions,
                                                                        individuals,
                                                                        bufferedData
                                                                      );

                                    CrossoverFunctions.crossover( individuals );

                                    MutationFunctions.mutation( individuals );

                                    generation++;
                                }

                                PairIndividualFitness bestInd = statisticFunctions.getBestIndividual();
                                accuracy[iterationCounter] = statisticFunctions.getAverageAccuracyAndF(true, bestInd.individual);
                                bestIndividuals[iterationCounter] = bestInd;


                                iterationCounter++;
                                repeatGeneration++;
                            }
                            shuffleIteration++;
                        }

                        //find best, avg and worst individual with bestIndividuals table
                        float[] acc_best_l = new float[] {0.0f, 0.0f};
                        float[] acc_best_t = new float[] {0.0f, 0.0f};
                        float[] acc_avg_l = new float[] {0.0f, 0.0f};
                        float[] acc_avg_t = new float[] {0.0f, 0.0f};
                        float[] acc_worst_l = new float[] {Float.MAX_VALUE, 0.0f};
                        float[] acc_worst_t = new float[] {Float.MAX_VALUE, 0.0f};
                        

                        for(int i = 0; i < tabLength; ++i) {
                            acc_avg_temp[i] = accuracy[i][0];
                            //System.out.println(acc_avg_temp[i]);
                        }
                        Arrays.sort(acc_avg_temp);
                        acc_avg_l[0] = acc_avg_temp[(tabLength+1)/2];
                        for(int i = 0; i < tabLength; ++i)
                            if(accuracy[i][0] == acc_avg_l[0]) {
                                acc_avg_l = accuracy[i];
                                acc_avg_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[i].individual);
                                break;
                            }
                        int acc_best_pos=0;
                        int acc_worst_pos=0;
                        for(int i = 0; i < tabLength; ++i) {
                            if(acc_best_l[0] < accuracy[i][0]) {
                                acc_best_l = accuracy[i];
                                acc_best_pos = i;
                            }
                            if(acc_worst_l[0] > accuracy[i][0]) {
                                acc_worst_l = accuracy[i];
                                acc_worst_pos = i;
                            }
                        }
                        acc_best_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[acc_best_pos].individual);
                        acc_worst_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[acc_worst_pos].individual);

                        String recordPlot = String.format(Locale.ENGLISH,"%d %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f",   generatrionTab[j],
                                                                                                                                             acc_best_l[0],
                                                                                                                                             acc_best_t[0],
                                                                                                                                             acc_avg_l[0],
                                                                                                                                             acc_avg_t[0],
                                                                                                                                             acc_worst_l[0],
                                                                                                                                             acc_worst_t[0],
                                                                                                                                             acc_best_l[1],
                                                                                                                                             acc_best_t[1],
                                                                                                                                             acc_avg_l[1],
                                                                                                                                             acc_avg_t[1],
                                                                                                                                             acc_worst_l[1],
                                                                                                                                             acc_worst_t[1]);
                        out = new BufferedWriter(new FileWriter(f, true));
                        out.write(recordPlot);
                        out.newLine();
                        out.write("# ");
                        for(int c = 0; c < Settings.CHROMOSOME_NUMBER_OF_CLUSTERS; ++c) {
                            for(int fe = 0; fe < Settings.CHROMOSOME_NUMBER_OF_FEATURES; ++fe)
                                out.write(bestIndividuals[acc_best_pos].individual.chromosomeVal.get(c).get(fe)+" ");
                            out.write("| ");
                        }
                        out.newLine();
                        out.close();
                        statisticFunctions.paintRecordsAndCentres(bestIndividuals[acc_best_pos].individual, "researchIndividualChanges_ff_"+ff+"_gen_"+generatrionTab[j]+"param_"+initialValue+"_"+step+"_"+howMany);
                }


                //-------------file out----------------
                out = new BufferedWriter(new FileWriter(f, true));
                out.write("#Finished computing: "+(new Date()));
                out.newLine();
                out.close();
                //-------------end file out----------------
                
            }
        } catch(Exception e) {
            System.out.println("Blad zapisu wynikow:\n"+e);
        }
    }

    public void researchPopulation() {

        if(bufferedData.data == null) {
            System.out.println("Brak danych!");
            return;
        }

        Settings.PROPABILITY_CROSSOVER = 0.0f;
        Settings.PROPABILITY_MUTATION = 0.01f;
        Settings.EXTERNAL_REPRODUCTION = false;

        int[] populationTab = new int[howMany]; //1000
        populationTab[0] = (int)initialValue;//0.1f
        float grad = step;//0.1f / pmSet.length;
        for(int i = 1; i < populationTab.length; ++i)
            populationTab[i] = (int) (populationTab[i - 1] + grad);

        int tabLength = Settings.SHUFFLE_PER_ITERATION * Settings.REPEAT_GENERATION_PER_ITERATION;

        float[][] accuracy = new float[ tabLength ][];
        PairIndividualFitness[] bestIndividuals = new PairIndividualFitness[ tabLength ];
        float[] acc_avg_temp = new float[tabLength];

        try {
            for(int ff = 0; ff < 3; ++ff) {
                Settings.FITNESS_FUNCTION_TYPE = ff;

                //-------------file out----------------
                String file = ff+"_acc_population_"+initialValue+"_"+step+"_"+howMany;
                File f = new File(file+".txt");
                BufferedWriter out = new BufferedWriter(new FileWriter(f));
                out.write("# badanie accuracy od populationn dla: 100 generation, replication non external, precision 8 bits, crossvalidation 5x10, set IRIS ");
                out.newLine();
                out.write("# fitnes fun:"+(ff==0?"euclides":"dbi")+", pc=0, pm=0.016 clusters=6");
                out.newLine();
                out.write("#Started computing: "+(new Date()));
                out.newLine();

                out.close();
                //-------------end file out----------------

                for(int j = 0; j < populationTab.length; ++j) {
                    Settings.POPULATION = populationTab[j];

                        //genetic algorithm
                        int shuffleIteration = 0;
                        int repeatGeneration = 0;
                        int iterationCounter = 0;

                        for(int i = 0; i < tabLength; ++i) {
                            accuracy[i] = new float[] {0, 0};
                            bestIndividuals[i] = null;
                        }


                        while(shuffleIteration < Settings.SHUFFLE_PER_ITERATION) {

                            bufferedData.shuffleData(Settings.NUMBER_OF_REPEAT_SHUFFLE_DATA);
                            repeatGeneration = 0;
                            while(repeatGeneration < Settings.REPEAT_GENERATION_PER_ITERATION) {

                                Initialization.initialization(individuals, bufferedData);
                                generation = 0;
                                while(generation < Settings.GENERATION) {

                                    ReproductionFunctions.reproduction( fitnessFunctions,
                                                                        individuals,
                                                                        bufferedData
                                                                      );

                                    CrossoverFunctions.crossover( individuals );

                                    MutationFunctions.mutation( individuals );

                                    generation++;
                                }

                                PairIndividualFitness bestInd = statisticFunctions.getBestIndividual();
                                accuracy[iterationCounter] = statisticFunctions.getAverageAccuracyAndF(true, bestInd.individual);
                                bestIndividuals[iterationCounter] = bestInd;


                                iterationCounter++;
                                repeatGeneration++;
                            }
                            shuffleIteration++;
                        }

                        //find best, avg and worst individual with bestIndividuals table
                        float[] acc_best_l = new float[] {0.0f, 0.0f};
                        float[] acc_best_t = new float[] {0.0f, 0.0f};
                        float[] acc_avg_l = new float[] {0.0f, 0.0f};
                        float[] acc_avg_t = new float[] {0.0f, 0.0f};
                        float[] acc_worst_l = new float[] {Float.MAX_VALUE, 0.0f};
                        float[] acc_worst_t = new float[] {Float.MAX_VALUE, 0.0f};


                        for(int i = 0; i < tabLength; ++i) {
                            acc_avg_temp[i] = accuracy[i][0];
                            //System.out.println(acc_avg_temp[i]);
                        }
                        Arrays.sort(acc_avg_temp);
                        acc_avg_l[0] = acc_avg_temp[(tabLength+1)/2];
                        for(int i = 0; i < tabLength; ++i)
                            if(accuracy[i][0] == acc_avg_l[0]) {
                                acc_avg_l = accuracy[i];
                                acc_avg_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[i].individual);
                                break;
                            }
                        int acc_best_pos=0;
                        int acc_worst_pos=0;
                        for(int i = 0; i < tabLength; ++i) {
                            if(acc_best_l[0] < accuracy[i][0]) {
                                acc_best_l = accuracy[i];
                                acc_best_pos = i;
                            }
                            if(acc_worst_l[0] > accuracy[i][0]) {
                                acc_worst_l = accuracy[i];
                                acc_worst_pos = i;
                            }
                        }
                        acc_best_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[acc_best_pos].individual);
                        acc_worst_t = statisticFunctions.getAverageAccuracyAndF(false, bestIndividuals[acc_worst_pos].individual);

                        String recordPlot = String.format(Locale.ENGLISH,"%d %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f %.4f",   populationTab[j],
                                                                                                                                             acc_best_l[0],
                                                                                                                                             acc_best_t[0],
                                                                                                                                             acc_avg_l[0],
                                                                                                                                             acc_avg_t[0],
                                                                                                                                             acc_worst_l[0],
                                                                                                                                             acc_worst_t[0],
                                                                                                                                             acc_best_l[1],
                                                                                                                                             acc_best_t[1],
                                                                                                                                             acc_avg_l[1],
                                                                                                                                             acc_avg_t[1],
                                                                                                                                             acc_worst_l[1],
                                                                                                                                             acc_worst_t[1]);
                        out = new BufferedWriter(new FileWriter(f, true));
                        out.write(recordPlot);
                        out.newLine();
                        out.write("# ");
                        for(int c = 0; c < Settings.CHROMOSOME_NUMBER_OF_CLUSTERS; ++c) {
                            for(int fe = 0; fe < Settings.CHROMOSOME_NUMBER_OF_FEATURES; ++fe)
                                out.write(bestIndividuals[acc_best_pos].individual.chromosomeVal.get(c).get(fe)+" ");
                            out.write("| ");
                        }
                        out.newLine();
                        out.close();
                        statisticFunctions.paintRecordsAndCentres(bestIndividuals[acc_best_pos].individual, "research_population_ff_"+ff+"_gen_"+populationTab[j]+"param_"+initialValue+"_"+step+"_"+howMany);
                }


                //-------------file out----------------
                out = new BufferedWriter(new FileWriter(f, true));
                out.write("#Finished computing: "+(new Date()));
                out.newLine();
                out.close();
                //-------------end file out----------------

            }
        } catch(Exception e) {
            System.out.println("Blad zapisu wynikow:\n"+e);
        }
    }

    public void researchIndividualChanges() {

        if(bufferedData.data == null) {
            System.out.println("Brak danych!");
            return;
        }

        Settings.PROPABILITY_CROSSOVER = 0.0f;
        Settings.PROPABILITY_MUTATION = 0.01f;
        Settings.EXTERNAL_REPRODUCTION = false;
        bufferedData.shuffleData(Settings.NUMBER_OF_REPEAT_SHUFFLE_DATA);
        
        try {
            for(int ff = 0; ff < 3; ++ff) {
                Settings.FITNESS_FUNCTION_TYPE = ff;
                generation = 0;
                Initialization.initialization(individuals, bufferedData);

                //-------------file out----------------
                String file = ff+"_acc_idividual_changes";
                File f = new File(file+".txt");
                BufferedWriter out = new BufferedWriter(new FileWriter(f));
                out.write("# badanie accuracy od generatrion in iteration dla: 50 population, replication non external, precision 8 bits, crossvalidation 5x10, set IRIS ");
                out.newLine();
                out.write("# fitnes fun:"+(ff==0?"euclides":"dbi")+", pc=0, pm=0.01 clusters=6");
                out.newLine();
                out.write("#Started computing: "+(new Date()));
                out.newLine();
                out.write("# Generation | Acc_learn | Acc_test | F_learn | F_test");
                out.newLine();

                PairIndividualFitness bestInd = statisticFunctions.getBestIndividual();
                float[] acc_best_l = statisticFunctions.getAverageAccuracyAndF(true, bestInd.individual);
                float[] acc_best_t = statisticFunctions.getAverageAccuracyAndF(false, bestInd.individual);
                String recordPlot = String.format(Locale.ENGLISH,"%d %.4f %.4f %.4f %.4f", generation,
                                                                                           acc_best_l[0],
                                                                                           acc_best_t[0],
                                                                                           acc_best_l[1],
                                                                                           acc_best_t[1]);
                out.write(recordPlot);
                out.newLine();
                out.write("# ");
                for(int c = 0; c < Settings.CHROMOSOME_NUMBER_OF_CLUSTERS; ++c) {
                    for(int fe = 0; fe < Settings.CHROMOSOME_NUMBER_OF_FEATURES; ++fe)
                        out.write(bestInd.individual.chromosomeVal.get(c).get(fe)+" ");
                    out.write("| ");
                }
                out.newLine();
                out.close();
                //-------------end file out----------------

                
                while(generation < Settings.GENERATION) {

                    ReproductionFunctions.reproduction( fitnessFunctions,
                                                        individuals,
                                                        bufferedData
                                                      );

                    CrossoverFunctions.crossover( individuals );

                    MutationFunctions.mutation( individuals );

                    bestInd = statisticFunctions.getBestIndividual();
                    acc_best_l = statisticFunctions.getAverageAccuracyAndF(true, bestInd.individual);
                    acc_best_t = statisticFunctions.getAverageAccuracyAndF(false, bestInd.individual);
                    recordPlot = String.format(Locale.ENGLISH,"%d %.4f %.4f %.4f %.4f", generation+1,
                                                                                               acc_best_l[0],
                                                                                               acc_best_t[0],
                                                                                               acc_best_l[1],
                                                                                               acc_best_t[1]);
                    out = new BufferedWriter(new FileWriter(f, true));
                    out.write(recordPlot);
                    out.newLine();
                    out.write("# ");
                    for(int c = 0; c < Settings.CHROMOSOME_NUMBER_OF_CLUSTERS; ++c) {
                        for(int fe = 0; fe < Settings.CHROMOSOME_NUMBER_OF_FEATURES; ++fe)
                            out.write(bestInd.individual.chromosomeVal.get(c).get(fe)+" ");
                        out.write("| ");
                    }
                    out.newLine();
                    out.close();
                    generation++;
                }

                //-------------file out----------------
                out = new BufferedWriter(new FileWriter(f, true));
                out.newLine();
                out.write("#Finished computing: "+(new Date()));
                out.newLine();
                out.close();
                //-------------end file out----------------

                statisticFunctions.paintRecordsAndCentres(bestInd.individual, "researchIndividualChanges_"+ff);
            }
        } catch(Exception e) {
            System.out.println("Blad zapisu wynikow:\n"+e);
        }
    }

//    public void run() {
//
//        if(bufferedData.data == null) {
//
//            System.out.println("Brak danych!");
//            return;
//
//        }
//
//
//        float[] pcSet = new float[] {0.01f, 0.05f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f};
////        float[] pmSet = new float[100];
////        pmSet[0] = 0.2f;
////        float grad = 0.1f / pmSet.length;
////        for(int i = 1; i < pmSet.length; ++i)
////            pmSet[i] = pmSet[i-1] + grad;
//
//        float[] pmSet = new float[] {0.01f};
//        //float[] pmSet = new float[] {0.0f};//0.0f, 0.0001f, 0.00025f, 0.0005f, 0.00075f, 0.001f, 0.0025f, 0.005f, 0.0075f, 0.01f};
//        int[] clusters = new int[] {3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
//        //int[] clusters = new int[] {13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
//
//        Settings.EXTERNAL_REPRODUCTION = false;
//        Settings.FITNESS_FUNCTION_TYPE = 0;
//
//        try {
//            //String file = "/home/krzysiek/NetBeansProjects/GenAlgClustering_turbo/badania/badania 1-3 maja/acc_pm";
//            for(int ff = 0; ff <2; ++ff) {
//                Settings.FITNESS_FUNCTION_TYPE = ff;
//
//                for (int i = 0; i < pcSet.length; i++) {
//                    Settings.PROPABILITY_CROSSOVER = pcSet[i];
//                    for(int j = 0; j < pmSet.length; ++j) {
//                        Settings.PROPABILITY_MUTATION = pmSet[j];
//
//                        //-------------file out----------------
//                        String file = "acc_clusters_fitfun_"+ff+"_pc_"+i;
//                        File f = new File(file+".txt");
//                        BufferedWriter out = new BufferedWriter(new FileWriter(f));
//                        //out.write("# badanie accuracy od pm dla: fitness-dbi, 450 generation, 200 population, replication non external, pc=0, precision 8 bits, 6 clusters, crossover 5x10, set IRIS ");
//                        out.write("# badanie accuracy od clusters dla: 450 generation, 200 population, replication non external, precision 8 bits, crossvalidation 5x10, set IRIS ");
//                        out.newLine();
//                        out.write("# fitnes fun:"+(ff==0?"euclides":"dbi")+", pc="+Float.toString(pcSet[i])+", pm=0.01");
//                        out.newLine();
//                        out.write("#Started computing: "+(new Date()));
//                        out.newLine();
//                        //-------------end file out----------------
//
//                        for(int cl = 0; cl < clusters.length; ++cl) {
//                            Settings.CHROMOSOME_NUMBER_OF_CLUSTERS = clusters[cl];
//
//                            //genetic algorithm
//                            int shuffleIteration = 0;
//                            int repeatGeneration = 0;
//                            Individual bestIndividual = null;
//                            double fitBestIndividual = 0;
//                            int iterationCounter = 0;
//                            while(shuffleIteration < Settings.SHUFFLE_PER_ITERATION) {
//
//                                bufferedData.shuffleData(Settings.NUMBER_OF_REPEAT_SHUFFLE_DATA);
//                                repeatGeneration = 0;
//                                while(repeatGeneration < Settings.REPEAT_GENERATION_PER_ITERATION) {
//
//                                    Initialization.initialization(individuals, bufferedData);
//                                    generation = 0;
//                                    while(generation < Settings.GENERATION) {
//
//                                        ReproductionFunctions.reproduction( fitnessFunctions,
//                                                                            individuals,
//                                                                            bufferedData
//                                                                          );
//
//                                        CrossoverFunctions.crossover( individuals );
//
//                                        MutationFunctions.mutation( individuals );
//
//                                        generation++;
//                                    }
//
//                                    PairIndividualFitness bestInd = statisticFunctions.getBestIndividual();
//                                    //Individual tempBestInd = statisticFunctions.getBestIndividual();
//                                    //float bestFitLVal = statisticFunctions.fitnessFunctions.fitness(tempBestInd, true);
//                                    if(fitBestIndividual < bestInd.fitness) {
//                                        fitBestIndividual = bestInd.fitness;
//                                        bestIndividual = bestInd.individual;
//                                    }
//
//                                    iterationCounter++;
//                                    //System.out.println("Iteration: "+iterationCounter);
//                                    repeatGeneration++;
//                                }
//                                shuffleIteration++;
//                            }
//                            String recordPlot = String.format(Locale.ENGLISH,"%d %.3f", clusters[cl], statisticFunctions.getAverageAccuracy(true, bestIndividual));
//                            out.write(recordPlot);
//                            out.newLine();
//                            //System.out.println(recordPlot);
//
//                        }
//
//                        //-------------file out----------------
//                        out.newLine();
//                        out.write("#Finished computing: "+(new Date()));
//                        out.newLine();
//                        out.close();
//                        //-------------end file out----------------
//
//                    }
//                }
//
//            }
//
///*
//            Process p = null;
//            try {
//                p = Runtime.getRuntime().exec("gnuplot");
//            }catch(Exception e) {
//                System.out.println("Blad gnuplota!");
//            }
//            OutputStream outputStream = p.getOutputStream();
//            PrintWriter gp=new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
//            gp.println("set terminal png\n");
//            gp.println("set yrange [0.0:100.0]\n");
//            gp.println("set xrange [0.0:0.0]\n");
//            gp.println("set xlabel \"Pm\"\n");
//            gp.println("set ylabel \"Accuracy\"\n");
//            gp.println("set output \""+file+".png\"\n");
//            gp.println("plot \""+file+".txt\" title 'Accuracy from Pm' with lines\n");
//            gp.close();
// */
//        } catch(Exception e) {
//            System.out.println("Blad zapisu wynikow:\n"+e);
//        }
//
//
//    }

}
